package com.gomoku.backend.consumer;

import com.alibaba.fastjson2.JSONObject;
import com.gomoku.backend.mapper.UserMapper;
import com.gomoku.backend.pojo.User;
import com.gomoku.backend.utils.JwtAuthentication;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.PathParam;
import javax.websocket.server.ServerEndpoint;
import java.io.IOException;
import java.util.Collections;
import java.util.Iterator;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArraySet;

@Component
@ServerEndpoint("/websocket/{token}")  // 注意不要以'/'结尾
public class WebSocketServer {
    private  Session session = null;//这个Session是websocket里面的包
    //每一个 new 的websocket都只有一个users 全局变量
    public final static ConcurrentHashMap<Integer, WebSocketServer> users = new ConcurrentHashMap<>();
    //这里是用来匹配的，所以断开链接就意味着退出，y总是这样的
    //private static CopyOnWriteArraySet<User> matchPool = new CopyOnWriteArraySet<>();
    private final static Set<User> mathPool = Collections.newSetFromMap(new ConcurrentHashMap<>()); //这个会按对象id排序来增加效率
    private User user;
    private static UserMapper userMapper;

    @Autowired
    public void setUserMapper(UserMapper usermapper){
        WebSocketServer.userMapper = usermapper;
    }

    private Game game = null;
    @OnOpen
    public void onOpen(Session session, @PathParam("token") String token) throws IOException {
        // 建立连接
        this.session=session; //每个链接通过session来维护
        System.out.println("Connected to websocket!");
        int userId = JwtAuthentication.getUserId(token);
        //接下来是通过用户id查到用户信息
        this.user = userMapper.selectById(userId);
        if(this.user!=null){
            users.put(userId,this);
        }else{
            this.session.close();
        }

        System.out.println(users);
    }

    @OnClose
    public void onClose() {
        // 关闭链接
        System.out.println("Disconnected from websocket!");
        if(this.user!=null) {
            users.remove(this.user.getId());
            mathPool.remove(this.user);
        }
    }

    public void startMatching(){
        System.out.println("Connected success!");
        mathPool.add(this.user);

        while(mathPool.size()>=2){
            Iterator<User> ite = mathPool.iterator();
            //默认a是先手黑棋，b是白棋
            User a = ite.next(), b = ite.next();
            mathPool.remove(a);
            mathPool.remove(b);

            Game game = new Game(16,16,a.getId(), b.getId());
            users.get(a.getId()).game = game;
            users.get(b.getId()).game = game;
            game.start();

            JSONObject respGame = new JSONObject();
            respGame.put("a_id",game.getPlayerA().getId());
            respGame.put("b_id",game.getPlayerB().getId());
            respGame.put("rows",game.getRows());
            respGame.put("cols",game.getCols());

            JSONObject respA = new JSONObject();
            respA.put("event","start-matching");
            respA.put("opponent_username",b.getUsername());
            respA.put("opponent_photo",b.getPhoto());
            respA.put("game",respGame);
            users.get(a.getId()).sendMessage(respA.toJSONString());

            JSONObject respB = new JSONObject();
            respB.put("event","start-matching");
            respB.put("opponent_username",a.getUsername());
            respB.put("opponent_photo",a.getPhoto());
            respB.put("game",respGame);
            users.get(b.getId()).sendMessage(respB.toJSONString());

        }
    }

    public void stopMatching(){
        System.out.println("Disconnected!");
        mathPool.remove(this.user);
    }
    public void move(Integer col,Integer row,Integer currentPlayer){
        //首先是判断一下当前的位置是否合法
        if(col <1 || col >this.game.getCols()-1 || row <1 || row>this.game.getRows())
            return;
        if(game.getBoard()[row][col] != 0)
            return;

        if(game.getPlayerA().getId().equals(user.getId()) || game.getPlayerB().getId().equals(user.getId())){ //只要是保证是当前链接的user就可以
            //System.out.println(col+" "+row);
            game.getBoard()[row][col] = game.getCurrentPlayer();

            if(game.getPlayerA().getId().equals(user.getId()) && currentPlayer == 1){
                game.setPlayerA(col,row);
                game.setNextStepA(true); //这个是不是可以把这个优化掉
            }else if(game.getPlayerB().getId().equals(user.getId()) && currentPlayer == 2){
                game.setPlayerB(col,row);
                game.setNextStepB(true);
            }
        }
    }
    @OnMessage
    public void onMessage(String message, Session session) {
        // 后端接受前端Client消息
        System.out.println("Received message: ");
        //前端通过send来发送一个信息
        JSONObject data = JSONObject.parseObject(message); //把这个字符串Json解析出来
        String event = data.getString("event");
        if("start-matching".equals(event)){
            startMatching();
        } else if("stop-matching".equals(event)){
            stopMatching();
        } else if("move".equals(event)){
            move(data.getInteger("col"),data.getInteger("row"),data.getInteger("currentPlayer"));
        }
    }

    @OnError
    public void onError(Session session, Throwable error) {
        error.printStackTrace();
    }

    //向前端发送信息，
    //例如 users.get(b.getId()) //通过ID取得 websocket
    //                      .sendMessage(respB.toJSONString());
    public void sendMessage(String message) {
        synchronized (this.session){ //异步通信需要加锁
            try {
                this.session.getBasicRemote().sendText(message); //后端向前端发送message，封装到data里面
            } catch (IOException e){
                e.printStackTrace();
            }
        }
    }
}